﻿package ygg.encoding.amf
{
	import flash.utils.ByteArray;
	import j.sus2maj7.encoding.*;
	
	public class AmfBinary extends AbstractBinary
	{
		
		public function AmfBinary(ba:ByteArray=null)
		{
			super(ba);
		}
		
		public function decodeU29(bSigned:Boolean = false):uint
		{
			trace('decodeU29');
			
			var u29:uint = 0;
			var n:int = 0;
			
			var u:uint = this.readUnsignedByte();
			trace(u, u.toString(16), u.toString(2) );
			while (u & 0x80 && n < 3)
			{
				u29 <<= 7;
				u29 |= u & 0x7F;
				
				u = this.readUnsignedByte();
				++n;
			}
			
			if (n < 3)
			{
				u29 <<= 7;
				u29 |= u; //high bit 0 so no need for & 0x7F
			}
			else
			{
				u29 <<= 8;
				u29 |= u;
				
				if (u29 & 0x10000000) //high bit 1
				{
					if (bSigned)
					{
						trace(u29, u29.toString(16), u29.toString(2) );
						u29 |= 0xE0000000;
						trace(u29, u29.toString(16), u29.toString(2) );
					}
					else // unsigned so *2+1
					{
						u29 <<= 1;
						u29 |= 1;
					}
				}
			}
				
			trace(u29, u29.toString(16), u29.toString(2) );
			return u29;
		}
	
		public function encodeU29(u:uint, bSigned:Boolean = false):void
		{
			trace('writeU29');
			trace(u, u.toString(16), u.toString(2) );
			
			//if (u > 0x3FFFFFFF) throw new RangeError('Out of Range');
			
			/*if (u & 0x20000000)
			{
				trace('neg');
				
				//u += 0xdfffffff;// u &= 0xfffffff
				trace(u, u.toString(16), u.toString(2) );
			}//*/
			
			if (u > 0x1FFFFF) //1x 1x 1x xx
			{
				
				this.writeByte( 0x80 | ((u >>> 22) & 0xff)  ); trace('> 0x1FFFFF', 0x80 | ((u >>> 22) & 0xff));
				this.writeByte( 0x80 | ((u >>> 15) & 0xff) ); trace('> 0x3FFF', 0x80 | ((u >>> 15) & 0xff));
				this.writeByte( 0x80 | ((u >>> 8) & 0xff) ); trace('> 0x7F', 0x80 | ((u >>> 8) & 0xff));
				this.writeByte( u & 0xFF); trace(u & 0xFF);
			}
			else if (u > 0x3FFF) //1x 1x 0x
			{
				
				this.writeByte( 0x80 | ((u >>> 14) & 0xff) ); trace('> 0x3FFF', 0x80 | ((u >>> 14) & 0xff));
				this.writeByte( 0x80 | ((u >>> 7) & 0xff));trace('> 0x7F', 0x80 | ((u >>> 7) & 0xff));
				this.writeByte( u & 0x7F);trace(u & 0x7F);
			}
			else if (u > 0x7F) //1x 0x
			{
				this.writeByte( 0x80 | ((u >>> 7) & 0xff)); trace('> 0x7F', 0x80 | ((u >>> 7) & 0xff));
				this.writeByte( u & 0x7F); trace(u & 0x7F);
				
			}
			else
			{
				this.writeByte( u & 0x7F);trace(u & 0x7F);
			}
			
		}
	}
}